package com.innovation.sys.controller;

import java.awt.image.BufferedImage;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import com.innovation.sys.common.dto.RelationForAccountDTO;
import com.innovation.sys.common.enums.Res;
import com.innovation.sys.common.utils.CodeUtils;
import com.innovation.sys.common.utils.PasswordUtils;
import com.innovation.sys.common.vo.BaseException;
import com.innovation.sys.common.vo.Ret;
import com.innovation.sys.pojo.SSysAccount;
import com.innovation.sys.pojo.SSysLog;
import com.innovation.sys.service.AccountService;
import com.innovation.sys.service.LogAdminService;

@Controller
@RequestMapping("/api/admin/sys/login")
public class LoginAdminController extends LogoutFilter {

	private static Logger logger = LoggerFactory.getLogger(LoginAdminController.class);

	@Resource
	private Producer kaptchaProducer;

	@Resource
	private RedisTemplate<String, String> redisTemplate;

	@Resource
	private LogAdminService logAdminService;

	@Resource
	private AccountService accountService;

	@RequestMapping(value = "/tologin", method = { RequestMethod.GET })
	public String tologin(ServletRequest request, ServletResponse response) {
		logger.info("跳转到登录界面===>");
		return "layuiAdmin/admin/login";
	}

	@ResponseBody
	@RequestMapping(value = "/login", method = { RequestMethod.POST })
	public String login(ServletRequest request, ServletResponse response, @RequestBody SSysAccount account) {
		logger.info("登录业务开始===>");
		HttpServletRequest req = (HttpServletRequest) request;
		try {
			if (CodeUtils.checkVerifyCode(req, account.getCode())) {
				Subject subject = SecurityUtils.getSubject();
				String password = PasswordUtils.encryptPassword(account.getUserName(), account.getPassword());
				UsernamePasswordToken token = new UsernamePasswordToken(account.getUserName(), password);
				subject.login(token);
				SSysAccount findByName = accountService.findByName(account.getUserName());
				String permission = this.getPermission(findByName.getAccountId());
				// 将信息存入session
				subject.getSession().setAttribute("user", findByName);
				subject.getSession().setAttribute("permission", permission);
				// 将用户信息存入redis
				ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
				opsForValue.set("user", findByName.getUserName());
				// 保存日志信息
				SSysLog sSysLog = new SSysLog();
				sSysLog.setCreateTime(new Date());
				sSysLog.setLogDesc("登录操作");
				sSysLog.setLogUser(account.getUserName());
				logAdminService.addLog(sSysLog);
				return JSON.toJSONString(Ret.ok(Res.COM_SUCCESS));
			} else {
				return JSON.toJSONString(Ret.fail(Res.USER_SMSCODE_NOTVALID));
			}
		} catch (AuthenticationException e) {
			logger.info("登录失败！登录的帐号为:{}" + account.toString());
			return JSON.toJSONString(Ret.fail(Res.USER_PASSWORD_WRONG));
		}
	}

	// 生成图形验证码
	@RequestMapping(value = "/code", method = { RequestMethod.GET })
	public void getKaptchaImage(HttpServletResponse response, HttpSession session) throws Exception {
		logger.info("生成验证码业务开始===>");
		ServletOutputStream out = null;
		try {
			response.setDateHeader("Expires", 0);
			response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
			response.addHeader("Cache-Control", "post-check=0, pre-check=0");
			response.setHeader("Pragma", "no-cache");
			response.setContentType("image/jpeg");
			String capText = kaptchaProducer.createText();
			// 将验证码存到session
			Subject subject = SecurityUtils.getSubject();
			subject.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);
			BufferedImage bi = kaptchaProducer.createImage(capText);
			out = response.getOutputStream();
			ImageIO.write(bi, "jpg", out);
			out.flush();
			out.close();
		} catch (Exception e) {
			logger.info("验证码生成异常！异常信息为:{}" + e.getMessage());
			Map<String, Object> map = new HashMap<>();
			map.put("code", Res.USER_SMSCODE_NOTVALID.getCode());
			map.put("message", Res.USER_SMSCODE_NOTVALID.getMsg());
			throw new BaseException(map);
		}
	}

	@RequestMapping(value = "/test", method = { RequestMethod.GET })
	public String test() {
		return "layuiAdmin/admin/main";
	}

	@RequestMapping(value = "/entry", method = { RequestMethod.GET })
	public String entry() {
		return "layuiAdmin/admin/main1";
	}

	private String getPermission(Integer accountId) {
		List<RelationForAccountDTO> findUserPermission = accountService.findUserPermission(accountId);
		String permission = "";
		for (RelationForAccountDTO relationForAccountDTO : findUserPermission) {
			permission += relationForAccountDTO.getPermission() + ",";
		}
		return permission;
	}

}
